// Copyright (c) Appeon. All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. 
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;

namespace SnapObjects.Data
{
    internal class ModelParameterHelper
    {
        public static IList<IAdoDbParameter> BindParameters(
            DataContext context, IReadOnlyList<ISqlParameter> sqlParameters, object[] parameters)
        {
            var result = new List<IAdoDbParameter>();

            if (sqlParameters == null || sqlParameters.Count == 0)
            {
                return result;
            }

            if (parameters == null || parameters.Length == 0)
            {
                throw new InvalidOperationException("Missing parameter value(s).");
            }

            var helper = context.AdoDbSqlProvider.SqlGenerationHelper;

            var paramValues = parameters
                .OfType<ParamValue>()
                .ToDictionary(x => x.Name, x => x, StringComparer.OrdinalIgnoreCase);

            // Ignore extra parameter(s), so not using parameters.Length
            for (var i = 0; i < sqlParameters.Count; i++)
            {
                var name = sqlParameters[i].Name;

                if (!paramValues.TryGetValue(name, out var paramValue))
                {
                    if (!(parameters[i] is ParamValue))
                    {
                        var dataType = sqlParameters[i]?.DataType ?? typeof(object);

                        paramValue = new ParamValue(
                            name, parameters[i], dataType, ParameterDirection.Input);
                    }
                    else
                    {
                        throw new InvalidOperationException(
                            $"Missing parameter value, parameter name: {name}.");
                    }
                }

                var adoDbParameter = new AdoDbParameter(paramValue)
                {
                    ParameterName = helper.GenerateParameterName(name),
                };

                result.Add(adoDbParameter);
            }

            return result;
        }

        public static IList<IAdoDbParameter> ConvertParameters(
            DataContext context,
            IReadOnlyList<ISqlParameter> sqlParameters)
        {
            var adoDbParameters = new List<IAdoDbParameter>();

            var helper = context.AdoDbSqlProvider.SqlGenerationHelper;

            foreach (var parameter in sqlParameters)
            {
                var adoDbParameter = new AdoDbParameter(parameter.Name, null, parameter.DataType)
                {
                    ParameterName = helper.GenerateParameterName(parameter.Name)
                };

                adoDbParameters.Add(adoDbParameter);
            }

            return adoDbParameters;
        }
    }
}
